#include "app.h"


#define MAX_RULES 50
typedef struct {
    uint8_t ipaddr[20];
    uint8_t mac[20];
} IPRule;

/* ----------------ip匹配规则---------------- */
IPRule whitelist[MAX_RULES] = {
    // 您指定的第一条规则
    {"192.168.4.2", "62:32:c3:3c:8f:6c"},

    // 补充的49条规则（实际使用时请替换为真实数据）
    {"192.168.4.3", "aa:bb:cc:dd:ee:ff"},
    {"192.168.4.4", "11:22:33:44:55:66"},
    {"192.168.4.5", "fe:dc:ba:98:76:54"},
    {"192.168.4.6", "9a:8b:7c:6d:5e:4f"},
    {"192.168.137.1", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 5-9
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 10-14
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 15-19
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 20-24
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 25-29
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 30-34
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 35-39
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""},  // 40-44
    {"", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""}   // 45-49
};
uint8_t rule_count = 6;

// // 快速线性匹配（满足<200us要求）
// /**
//  * @brief 检查IP和MAC是否在白名单中
//  * 
//  * @param ip IPv4地址字符串（如"192.168.1.1"）
//  * @param mac MAC地址字符串（如"aa:bb:cc:dd:ee:ff"）
//  * @return true 如果在白名单中找到匹配
//  * @return false 如果不在白名单中
//  */
// bool is_in_whitelist(const char *ip, const char *mac) {
//     // 空指针检查
//     if (!ip || !mac) return false;
    
//     // 计算输入字符串长度
//     size_t ip_len = strlen(ip);
//     size_t mac_len = strlen(mac);
    
//     // 简单长度验证（IPv4最多15字符+null，MAC固定17字符+null）
//     if (ip_len >= 16 || mac_len >= 18) return false;
    
//     for (int i = 0; i < MAX_RULES; i++) {
//         // 跳过空规则
//         if (whitelist[i].ipaddr[0] == '\0' || whitelist[i].mac[0] == '\0') {
//             continue;
//         }
        
//         // 比较IP和MAC
//         if (strcmp((char *)whitelist[i].ipaddr, ip) == 0 && 
//             strcmp((char *)whitelist[i].mac, mac) == 0) {
//             return true;
//         }
//     }
    
//     return false;
// }

/**
 * @brief 仅检查IP是否在白名单中
 * 
 * @param ip IPv4地址字符串
 * @return true 如果IP在白名单中
 * @return false 如果IP不在白名单中
 */
bool is_ip_in_whitelist(const char *ip) {
    if (!ip) return false;
    size_t ip_len = strlen(ip);
    if (ip_len >= 16) return false;
    
    for (int i = 0; i < MAX_RULES; i++) {
        if (whitelist[i].ipaddr[0] == '\0') continue;
        if (strcmp((char *)whitelist[i].ipaddr, ip) == 0) {
            return true;
        }
    }
    
    return false;
}

// /**
//  * @brief 仅检查MAC是否在白名单中
//  * 
//  * @param mac MAC地址字符串
//  * @return true 如果MAC在白名单中
//  * @return false 如果MAC不在白名单中
//  */
// bool is_mac_in_whitelist(const char *mac) {
//     if (!mac) return false;
//     size_t mac_len = strlen(mac);
//     if (mac_len >= 18) return false;
    
//     for (int i = 0; i < MAX_RULES; i++) {
//         if (whitelist[i].mac[0] == '\0') continue;
//         if (strcmp((char *)whitelist[i].mac, mac) == 0) {
//             return true;
//         }
//     }
    
//     return false;
// }

// /* ----------------SYN Flood检测实现---------------- */

// ================ 硬件依赖配置 ================
#define MAX_TRACKED_IPS   10    // 最大追踪IP数量
#define SYN_THRESHOLD     30    // 每秒SYN包阈值

// ================ TCP状态定义 ================
typedef enum {
    TCP_CLOSED,      // 0
    TCP_LISTEN,      // 1
    TCP_SYN_SENT,    // 2
    TCP_SYN_RECV,    // 3  <- 关键状态（收到SYN未完成握手）
    TCP_ESTABLISHED, // 4
    TCP_FIN_WAIT1,   // 5
    TCP_FIN_WAIT2,   // 6
    TCP_CLOSE_WAIT,  // 7
    TCP_CLOSING,     // 8
    TCP_LAST_ACK,    // 9
    TCP_TIME_WAIT    // 10
} TcpState;

// ================ 连接状态结构体（优化内存） ================
typedef struct {
    uint32_t ip;            // 客户端IP（网络字节序）
    uint16_t port;          // 客户端端口
    uint8_t state : 4;      // TcpState（4位足够）
    uint8_t syn_retry : 3;  // SYN重试次数
    uint8_t is_blocked : 1; // 是否已被阻断
} IpInfo;

// ================ 全局变量 ================
static IpInfo ip_table[MAX_TRACKED_IPS];
static uint32_t last_syn_flood_check = 0;

// ================ 核心函数 ================

/**
 * @brief 将字符串IP转为网络字节序的32位整数
 * @param ip_str 点分十进制IP（如"192.168.1.1"）
 * @return 网络字节序IP
 */
uint32_t IP_To_Uint32(const char* ip_str) {
    uint8_t octets[4];
    sscanf(ip_str, "%hhu.%hhu.%hhu.%hhu", &octets[0], &octets[1], &octets[2], &octets[3]);
    return (octets[0]<<24) | (octets[1]<<16) | (octets[2]<<8) | octets[3];
}
/**
 * @brief 将网络字节序的32位整数转为点分十进制IP字符串
 * @param ip 网络字节序IP
 * @param buf 输出缓冲区（至少16字节）
 * @return 转换后的字符串地址（同buf）
 */
char* Uint32_To_IP(uint32_t ip, char* buf) {
    uint8_t* octets = (uint8_t*)&ip;
    snprintf(buf, 16, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
    return buf;
}

/**
 * @brief 阻断指定IP（通过防火墙规则）
 */
void Block_IP(uint32_t ip) {
    char ip_str[16];
    Uint32_To_IP(ip, ip_str);
    // 白名单不阻断
    bool ret = is_ip_in_whitelist(ip_str);
    if(ret)
    {
        return;
    }
        char cmd[64];
        uint8_t octet[4];
            
        octet[0] = (ip >> 24) & 0xFF;
        octet[1] = (ip >> 16) & 0xFF;
        octet[2] = (ip >> 8) & 0xFF;
        octet[3] = ip & 0xFF;
        sprintf(cmd, "AT+CIPBLOCK=ADD,\"%d.%d.%d.%d\"\r\n", 
                octet[0], octet[1], octet[2], octet[3]);
        HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), 100);
}

/**
 * @brief 更新IP状态表（核心检测逻辑）
 */
void Update_IP_Table(uint32_t ip, uint16_t port, TcpState state) {
    // 查找是否已记录该IP
    int free_slot = -1;
    for (int i = 0; i < MAX_TRACKED_IPS; i++) {
        if (ip_table[i].ip == ip) {
            // 状态转移检测
            if (ip_table[i].state == TCP_SYN_RECV && state == TCP_ESTABLISHED) {
                ip_table[i].syn_retry = 0; // 重置计数器（握手完成）
            }
            ip_table[i].state = state;
            return;
        }
        if (free_slot == -1 && ip_table[i].ip == 0) {
            free_slot = i; // 记录空闲位置
        }
    }

    // 新IP记录（仅跟踪SYN_RECV状态）
    if (free_slot != -1 && state == TCP_SYN_RECV) {
        ip_table[free_slot].ip = ip;
        ip_table[free_slot].port = port;
        ip_table[free_slot].state = state;
        ip_table[free_slot].syn_retry++;
            
        // 检测SYN重传（攻击特征）
        if (ip_table[free_slot].syn_retry > 2) {
            Block_IP(ip); // 阻断恶意IP
        }
    }
}

/**
 * @brief 解析TCP状态响应（关键函数）
 * @param resp 模块响应（格式：+CIPSTATUS:<link>,<type>,<remote_ip>,<remote_port>,<local_port>,<state>）
 * @note 示例：+CIPSTATUS:0,"TCP","192.168.1.100",12345,8080,3
 */
void Parse_TCP_State(const char* resp) {
    uint8_t link_id, state;
    char ip_str[16];
    uint16_t remote_port;
    
    if (sscanf(resp, "+CIPSTATUS:%hhu,\"TCP\",\"%15[^\"]\",%hu", 
              &link_id, ip_str, &remote_port) >= 3) {
        // 提取TCP状态（最后一个参数）
        const char* state_ptr = strrchr(resp, ',');
        if (state_ptr) state = atoi(state_ptr + 1);
        // 白名单不监视
        bool ret = is_ip_in_whitelist(ip_str);
        if(ret)
        {
            printf("Not monitored on the whitelist resp:%s\n", resp);
            return;
        }

        uint32_t ip = IP_To_Uint32(ip_str);
        Update_IP_Table(ip, remote_port, (TcpState)state);
    }
}

void Trigger_Alarm(void) {
    //触发蜂鸣器
    HAL_GPIO_WritePin(GPIOC, BEEP_ACTIVE_Pin, GPIO_PIN_SET);
}

/**
 * @brief 定时SYN洪水检测（每1秒调用）
 */
void Check_SYN_Flood() {
    uint32_t current = HAL_GetTick();
    if (current - last_syn_flood_check < 1000) return;
    
    last_syn_flood_check = current;
    uint16_t syn_count = 0;

    // 统计当前半开连接数
    for (int i = 0; i < MAX_TRACKED_IPS; i++) {
        if (ip_table[i].state == TCP_SYN_RECV) {
            syn_count++;
        }
    }

    // 触发阈值判断
    if (syn_count > SYN_THRESHOLD) {
        Trigger_Alarm();
        // 自动阻断最新攻击IP
        for (int i = MAX_TRACKED_IPS - 1; i >= 0; i--) {
            if (ip_table[i].state == TCP_SYN_RECV) {
                Block_IP(ip_table[i].ip);
                break;
            }
        }
    }
}


void Handle_SYN_Check_State(void) {

    // 每秒检测SYN洪水
    Check_SYN_Flood();
}
